package com.zzl.alligator.framework.config;

import com.github.benmanes.caffeine.cache.CacheLoader;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.zzl.alligator.framework.cache.support.CacheSpecEnum;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.caffeine.CaffeineCache;
import org.springframework.cache.support.SimpleCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import java.util.ArrayList;
import java.util.concurrent.TimeUnit;

/**
 * TODO
 *
 * @author zhouziliang
 * @since 2020/6/26
 */
@Slf4j
@Configuration
@EnableCaching
public class CaffeineCacheConfig {

    @Bean
    public CacheLoader<Object, Object> cacheLoader() {
        CacheLoader<Object, Object> cacheLoader = new CacheLoader<Object, Object>() {
            @Nullable
            @Override
            public Object load(@NonNull Object key) throws Exception {
                return null;
            }

            @Nullable
            @Override
            public Object reload(@NonNull Object key,
                                 @NonNull Object oldValue) throws Exception {
                return oldValue;
            }
        };
        return cacheLoader;
    }

    @Bean
    @Primary
    public CacheManager cacheManager() {
        SimpleCacheManager simpleCacheManager = new SimpleCacheManager();
        ArrayList<CaffeineCache> caches = new ArrayList<>();
        for (CacheSpecEnum cacheSpec : CacheSpecEnum.values()) {
            caches.add(new CaffeineCache(cacheSpec.name(),
                    Caffeine.newBuilder().recordStats()
                            .expireAfterWrite(cacheSpec.getTtl(), TimeUnit.SECONDS)
                            .maximumSize(cacheSpec.getMaxSize())
                            .build())
            );
        }
        simpleCacheManager.setCaches(caches);
        return simpleCacheManager;
    }

}
